﻿using iS3.DAL.Attributes;
using iS3.DAL.Table;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace iS3.DAL
{
    /// <summary>
    ///  the struct of entity
    /// </summary>
    [TableName("System_DGEntityStruct")]
    public class DGEntityStruct:DGEntity
    {

        public string Type { get; set;}   //sys,project   系统库 项目库
        public string Param { get; set; }   //参数 
        public string Source { get; set; }   //来源
        public string Desc { get; set; }
        

        private string _entityTypeName;
        public string EntityTypeName
        {
            get { return _entityTypeName; }
            set { _entityTypeName = value; }
        }
        private string _entityDomain;
        public string EntityDomain
        {
            get { return _entityDomain; }
            set { _entityDomain = value; }
        }
        private string _entityTypeCode;
        public string EntityTypeCode
        {
            get { return _entityTypeCode; }
            set { _entityTypeCode = value; }
        }

        private string _tableName;
        public string TableName
        {
            get { return _tableName; }
            set { _tableName = value; }
        }
        private string _entityViewType;
        public string EntityViewType
        {
            get { return _entityViewType; }
            set { _entityViewType = value; }
        }
        private string _defaultViewPath;
        public string DefaultViewPath
        {
            get { return _defaultViewPath; }
            set { _defaultViewPath = value; }
        }
        private bool _defaultView2Pos;
        public bool DefaultView2Pos
        {
            get { return _defaultView2Pos; }
            set { _defaultView2Pos = value; }
        }

        [NotMapped]
        public List<DGPropertyStruct> StructList { get; set; }
        //[NotMapped]
        //public List<DGPropertyStruct> StructList
        //{
        //    get { return structList; }
        //}
        public List<DGPropertyStruct> getSimpleStructList()
        {
            List<DGPropertyStruct> res = new List<DGPropertyStruct>();
            StructList.ForEach(x =>
            {
                if ((x.Target != "sys") && (!x.IsPrimaryKey))
                {
                    res.Add(x);
                }
            });
            return res;
        }
        public DGEntityStruct()
        {
            StructList = new List<DGPropertyStruct>();
        }
        public DGEntityStruct(string entityTypeCode)
        {
            this._entityTypeCode = entityTypeCode;
            StructList = new List<DGPropertyStruct>();
        }
        public DGEntityStruct DeepClone()
        {
            return Newtonsoft.Json.JsonConvert.DeserializeObject<DGEntityStruct>(Newtonsoft.Json.JsonConvert.SerializeObject(this));
        }
        public DGEntityStruct SimpleClone()
        {
            DGEntityStruct newOne = DeepClone();
            newOne.StructList = new List<DGPropertyStruct>();
            return newOne;
        }
        public void Add(DGPropertyStruct _struct)
        {
            StructList.Add(_struct);
        }
        public string keyCode()
        {
            if (this.Type == "project")
            {
                return string.Format("project@{0}@{1}", this.Param, this.EntityTypeCode);
            }
            else
            {
                return string.Format("{0}@{1}", this.Type, this.EntityTypeCode);
            }
        }

        public DGPropertyStruct PrimaryKey()
        {
            return StructList.Where(x => x.IsPrimaryKey).FirstOrDefault();
        }
        /*
         * 添加系统默认所需的字段
         */
        public static void AppendExternalProperties(DGEntityStruct dgStruct)
        {

        }
        public static DGEntityStruct LoadDesc(Type typeInfo)
        {
            DGEntityStruct result = new DGEntityStruct(typeInfo.Name);

            //table Name
            object[] tableNameAtts = iS3ReflectTool.GetAttributes(typeInfo, typeof(TableNameAttribute));
            if ((tableNameAtts == null) || (tableNameAtts.Length == 0))
            {
                result.TableName = result.EntityTypeName;   //若没有设置，则数据表表名与实体名称一致
            }
            else
            {
                result.TableName = (tableNameAtts[0] as TableNameAttribute).TableName;
            }

            //entity type
            object[] entityTypeAtts = iS3ReflectTool.GetAttributes(typeInfo, typeof(DGEntityTypeAttribute));
            if ((entityTypeAtts == null) || (entityTypeAtts.Length == 0))
            {
                
            }
            else
            {
                result.EntityDomain = (entityTypeAtts[0] as DGEntityTypeAttribute).Domain;
                result.EntityTypeName = (entityTypeAtts[0] as DGEntityTypeAttribute).DGName;

            }

            //property name
            List<PropertyInfo> piList = iS3ReflectTool.GetPropertyList(typeInfo);
            foreach (PropertyInfo pi in piList)
            {
                DGPropertyStruct dps = new DGPropertyStruct();
                dps.PropertyName = pi.Name;
                dps.SqlType = iS3DataType.GetSqlType(pi.PropertyType);

                object[] notAtts = iS3ReflectTool.GetAttributes(pi, typeof(NotMappedAttribute));

                if (!((notAtts == null) || (notAtts.Length == 0)))
                {
                    continue;
                }


                //key
                object[] keyAtts = iS3ReflectTool.GetAttributes(pi, typeof(PropertyKeyAttribute));
                if ((keyAtts == null) || (keyAtts.Length == 0))
                {
                    dps.IsPrimaryKey = false;
                    dps.IsAutoIncrement = false;
                    dps.IsCanNull = true;
                }
                else
                {
                    PropertyKeyAttribute keyAttr = (keyAtts[0] as PropertyKeyAttribute);
                    dps.IsPrimaryKey = keyAttr.IsPrimaryKey;
                    dps.IsAutoIncrement = keyAttr.IsAutoIncrement;
                    dps.IsCanNull = keyAttr.IsCanNull;
                }

                //propertyName
                object[] propertyAtts = iS3ReflectTool.GetAttributes(pi, typeof(PropertyNameAttribute));
                if ((propertyAtts == null) || (propertyAtts.Length == 0))
                {
                    dps.ChsName = null;
                }
                else
                {
                    PropertyNameAttribute propertyAtt = (propertyAtts[0] as PropertyNameAttribute);
                    dps.ChsName = propertyAtt.ChsName;
                 }

                //Description
                object[] descriptionAtts = iS3ReflectTool.GetAttributes(pi, typeof(PropertyDescriptionAttribute));
                if ((descriptionAtts == null) || (descriptionAtts.Length == 0))
                {
                    dps.Description = null;
                }
                else
                {
                    PropertyDescriptionAttribute descriptionAtt = (descriptionAtts[0] as PropertyDescriptionAttribute);
                    dps.Description = descriptionAtt.Description;
                }

                //Dispaly
                object[] displayAtts = iS3ReflectTool.GetAttributes(pi, typeof(PropertyDisplayAttribute));
                if ((displayAtts == null) || (displayAtts.Length == 0))
                {
                    dps.IsCanIgnore = false;
                    dps.IsCanOrder = false;
                    dps.MaxLength = -1;
                }
                else
                {
                    PropertyDisplayAttribute displaynAtt = (displayAtts[0] as PropertyDisplayAttribute);
                    dps.IsCanIgnore = displaynAtt.IsCanIgnore;
                    dps.IsCanOrder = displaynAtt.IsCanOrder;
                    dps.MaxLength = displaynAtt.MaxLength;
                }

                //external
                object[] externalAtts = iS3ReflectTool.GetAttributes(pi, typeof(PropertyExternalAttribute));
                if ((externalAtts == null) || (externalAtts.Length == 0))
                {
                    dps.Unit = null;
                    dps.Example = null;
                }
                else
                {
                    PropertyExternalAttribute externalAttr = (externalAtts[0] as PropertyExternalAttribute);
                    dps.Unit = externalAttr.Unit;
                    dps.Example = externalAttr.Example;
                    dps.Target = externalAttr.Target;
                }


                result.Add(dps);
            }

            return result;
        } 

        public static DataTable TransformToDataTable(Type typeInfo,IEnumerable list)
        {
            DGEntityStruct des = DGEntityManager.GetInstance().GetStruct(typeInfo);
            List<PropertyInfo> piList = DGEntityManager.GetInstance().GetPropertys(typeInfo);

            DataTable dt = new DataTable();
            for (int i = 0; i < des.StructList.Count; i++)
            {
                dt.Columns.Add(des.StructList[i].PropertyName);
            }
            foreach (var data in list)
            {
                DataRow dr = dt.NewRow();
                foreach (var pi in piList)
                {
                    try
                    {
                        dr[pi.Name] = pi.GetValue(data);
                        //if ((pi.PropertyType == typeof(DateTime)) && (dr[pi.Name] == null))
                        //{
                        //    dr[pi.Name] = System.Data.SqlTypes.SqlDateTime.MinValue;
                        //}
                    }
                    catch (Exception ex)
                    {
 
                    }

                }
                dt.Rows.Add(dr);
            }
            return dt;
        }

        //public static List<TEntity> TransformToEntity<TEntity>(DataTable dataTable) where TEntity : DGBase,new()
        //{
        //    List<TEntity> res = new List<TEntity>();
        //    List<PropertyInfo> piList = DGEntityManager.GetInstance().GetPropertys(typeof(TEntity));
        //    if (dataTable.Rows.Count > 0)
        //    {
        //        for (int i = 0; i < dataTable.Rows.Count; i++)
        //        {
        //            TEntity _one = new TEntity();
        //            foreach (PropertyInfo _pi in piList)
        //            {
        //                try
        //                {
        //                    string _outValue = dataTable.Rows[i][_pi.Name].ToString();
        //                    _one.SetValue()
        //                    _pi.SetValue(_one, Convert.ChangeType(_outValue, _pi.PropertyType));
        //                }
        //                catch (Exception ex)
        //                {
        //                    _pi.SetValue(_one, null);
        //                }

        //            }
        //            res.Add(_one);
        //        }
        //    }
        //    return res;
        //}
    }
}
